package entity

import (
	"sen-golang-study/go_game_study/hero_story_go_server/game_server/internal/domain/session/valueobject"
	"time"
)

// Session 会话聚合根
type Session struct {
	sessionID       string
	gatewayID       uint32
	remoteSessionID uint32
	userID          uint32
	clientIPAddr    string
	status          valueobject.SessionStatus
	createTime      int64
	lastActiveTime  int64
}

// NewSession 创建新会话
func NewSession(sessionID string, gatewayID, remoteSessionID uint32) *Session {
	now := time.Now().UnixMilli()
	return &Session{
		sessionID:       sessionID,
		gatewayID:       gatewayID,
		remoteSessionID: remoteSessionID,
		userID:          0,
		clientIPAddr:    "",
		status:          valueobject.SessionStatusActive,
		createTime:      now,
		lastActiveTime:  now,
	}
}

// GetSessionID 获取会话ID
func (s *Session) GetSessionID() string {
	return s.sessionID
}

// GetGatewayID 获取网关ID
func (s *Session) GetGatewayID() uint32 {
	return s.gatewayID
}

// GetRemoteSessionID 获取远程会话ID
func (s *Session) GetRemoteSessionID() uint32 {
	return s.remoteSessionID
}

// GetUserID 获取用户ID
func (s *Session) GetUserID() uint32 {
	return s.userID
}

// BindUser 绑定用户
func (s *Session) BindUser(userID uint32) {
	s.userID = userID
	s.UpdateLastActiveTime()
}

// UnbindUser 解绑用户
func (s *Session) UnbindUser() {
	s.userID = 0
	s.UpdateLastActiveTime()
}

// GetClientIPAddr 获取客户端IP地址
func (s *Session) GetClientIPAddr() string {
	return s.clientIPAddr
}

// SetClientIPAddr 设置客户端IP地址
func (s *Session) SetClientIPAddr(clientIPAddr string) {
	s.clientIPAddr = clientIPAddr
}

// GetStatus 获取会话状态
func (s *Session) GetStatus() valueobject.SessionStatus {
	return s.status
}

// SetStatus 设置会话状态
func (s *Session) SetStatus(status valueobject.SessionStatus) {
	s.status = status
	s.UpdateLastActiveTime()
}

// GetCreateTime 获取创建时间
func (s *Session) GetCreateTime() int64 {
	return s.createTime
}

// GetLastActiveTime 获取最后活跃时间
func (s *Session) GetLastActiveTime() int64 {
	return s.lastActiveTime
}

// UpdateLastActiveTime 更新最后活跃时间
func (s *Session) UpdateLastActiveTime() {
	s.lastActiveTime = time.Now().UnixMilli()
}

// IsActive 判断会话是否活跃
func (s *Session) IsActive() bool {
	return s.status == valueobject.SessionStatusActive
}

// IsExpired 判断会话是否过期
func (s *Session) IsExpired(timeoutMs int64) bool {
	now := time.Now().UnixMilli()
	return now-s.lastActiveTime > timeoutMs
}

// Close 关闭会话
func (s *Session) Close() {
	s.status = valueobject.SessionStatusClosed
	s.UpdateLastActiveTime()
}

// IsUserBound 判断是否已绑定用户
func (s *Session) IsUserBound() bool {
	return s.userID > 0
}